//题目:
// 给定三个字符串 s1、s2、s3，请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。
// 两个字符串 s 和 t 交错 的定义与过程如下，其中每个字符串都会被分割成若干 非空 
// 子字符串：
// s = s1 + s2 + ... + sn
// t = t1 + t2 + ... + tm
// |n - m| <= 1
// 交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...
// 注意：a + b 意味着字符串 a 和 b 连接。
#include<iostream>
#include<vector>

using namespace std;
//代码
class Solution 
{
    string s1,s2,s3;
    bool ret=false;
public:
    bool dfs(int pos1,int pos2,int pos3)
    {
        if(pos3==s3.size()) {
            if(pos1==s1.size() && pos2==s2.size()) return true;
            return false;
        }
        if(s3[pos3]==s1[pos1] && dfs(pos1+1,pos2,pos3+1)==true)
            return true;
        if(s3[pos3]==s2[pos2] && dfs(pos1,pos2+1,pos3+1)==true)
            return true;

        return false;
    }
    bool isInterleave(string _s1, string _s2, string _s3) 
    {
        if( _s3.size()!=_s1.size()+_s2.size())
            return false;
        //法一：全排列————超时
        s1=_s1,s2=_s2,s3=_s3;
        // return dfs(0,0,0);

        s1=" "+s1,s2=" "+s2,s3=" "+s3;
        int n1=s1.size(),n2=s2.size(),n3=s3.size();
        //法二：动态规划
        //1.创建dp表————dp[i][j]表示：s1中[0,i]子串与s2中[0,j]子串是否能构成s3中[0,i+j]子串
        vector<vector<bool>> dp(n1,vector<bool>(n2));
        //2.初始化
        dp[0][0]=true;
        for(int i=1;i<n1;i++) if(s1[i]==s3[i]) dp[i][0]=true; else break;
        for(int j=1;j<n2;j++) if(s2[j]==s3[j]) dp[0][j]=true; else break;
        //3.填表
        int pos1=1,pos2=1;
        for(int i=1;i<n1;i++)
        {
            for(int j=1;j<n2;j++)
            {
                if(s1[i]==s3[i+j]) dp[i][j]=dp[i-1][j];
                if(s2[j]==s3[i+j]) dp[i][j]=dp[i][j] || dp[i][j-1];
            }
        }
        //4.确定返回值
        return dp[n1-1][n2-1];
    }
};